package com.hugh.dubbo.data;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: Hugh
 * @Date: 2020/7/5
 */
@Slf4j
public abstract class BaseDataComputService implements DataComputService{

    protected Map<String, List<Long>> currentHandledData;

    private Long latestMills = 60000L;
    /**
     *
     * @return 此次计算的数据集
     */
    @Override
    public void getAndComputData(){
        //取当前最新的1分钟的数据
        Map<String, List<Long>> latestRtCollention = MonitorData.getLatestRtCollention(latestMills);
        log.info("getAndComputData:res{}", JSON.toJSON(latestRtCollention));
        if(CollectionUtils.isEmptyMap(latestRtCollention)){
            currentHandledData = Collections.emptyMap();
        }
        if(CollectionUtils.isNotEmptyMap(latestRtCollention)){
            Map<String, List<Long>> currentHandledData = new ConcurrentHashMap<>();
            Iterator<Map.Entry<String, List<Long>>> iterator = latestRtCollention.entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<String, List<Long>> next = iterator.next();
                List<Long> value = next.getValue();
                Collections.sort(value);
                currentHandledData.put(next.getKey(), value);

            }
            this.currentHandledData = currentHandledData;
        }
    }

    /**
     * 计算最近1分钟内方法的TP90
     */
    @Override
    public void computDataTp90(){
        if(CollectionUtils.isEmptyMap(currentHandledData)){
            this.getAndComputData();
        }
        if(CollectionUtils.isEmptyMap(currentHandledData)){
            log.info("路径path :{} 的TP90是:{} ms", null, null);
            return;
        }
        Iterator<Map.Entry<String, List<Long>>> iterator = currentHandledData.entrySet().iterator();
        long min = latestMills / 60000L;
        while (iterator.hasNext()){
            Map.Entry<String, List<Long>> next = iterator.next();
            List<Long> value = next.getValue();
            BigDecimal tp90 = BigDecimal.valueOf(value.size() * 0.9).setScale(0, RoundingMode.HALF_DOWN);
            log.info("路径path :{} 的最近 {} 分钟的 TP90是:{} ms", next.getKey(), min, value.get(tp90.intValue() -1 ));
        }
    }

    /**
     * 计算最近1分钟内方法的TP99
     */
    @Override
    public void computDataTp99(){
        if(CollectionUtils.isEmptyMap(currentHandledData)){
            this.getAndComputData();
        }
        if(CollectionUtils.isEmptyMap(currentHandledData)){
            log.info("路径path :{} 的TP90是:{} ms", null, null);
            return;
        }
        Iterator<Map.Entry<String, List<Long>>> iterator = currentHandledData.entrySet().iterator();
        long min = latestMills / 60000L;
        while (iterator.hasNext()){
            Map.Entry<String, List<Long>> next = iterator.next();
            List<Long> value = next.getValue();
            BigDecimal tp99 = BigDecimal.valueOf(value.size() * 0.99).setScale(0, RoundingMode.HALF_DOWN);
            log.info("路径path :{} 的最近 {} 分钟的 TP99是:{} ms", next.getKey(), min, value.get(tp99.intValue() - 1));
        }
    }
}
